
/*Class  v- 1.0*/
(function (window) {
	'use strict';
	var VERSION = '1.0';
	var ORIGINAL = window.Class;
	var Class = window.Class = function (obj) {
		obj = obj || {};
		var constructor = function () {
			return (this.initialize) ? this.initialize.apply(this, arguments) : self;
		};
		if (obj.implement) {
			var self = window === this ? copy(constructor.prototype) : this;
			var imp = obj.implement;
			remove(obj, 'implement');
			obj = extend(obj, implement(imp));
		}
		constructor.prototype = copy(obj);
		constructor.constructor = constructor;
		constructor._parent = copy(obj);
		for (var i = 0, values = ['extend', 'implement', 'getOptions', 'setOptions']; i < values.length; i++) {
			constructor[values[i]] = Class[values[i]];
		}
		return constructor;
	};
	Class.extend = function (obj) {
		var self = this;
		if (obj.implement) {
			this.prototype = extend(this.prototype, implement(obj.implement));
			remove(obj, 'implement');
		}
		for (var key in obj) {
			obj[key] = typeof obj[key] === 'function' && /parent/.test(obj[key].toString()) ? (function (method, name) {
				return function () {
					this.parent = self._parent[name];
					return method.apply(this, arguments);
				};
			})(obj[key], key) : obj[key]
		}
		this._parent = extend(this._parent, obj, true);
		this.prototype = extend(this.prototype, obj);
		return this;
	};
	Class.implement = function (array) {
		return this.prototype = extend(this.prototype, implement(array));
	};
	Class.getOptions = function () {
		return this.prototype.options || {};
	};
	Class.setOptions = function (options) {
		return this.prototype.options = extend(this.prototype.options, options);
	};
	Class.noConflict = function () {
		window.Class = ORIGINAL;
		return Class;
	};
	Class.version = VERSION;

	function copy(obj) {
		var F = function () {};
		F.prototype = obj.prototype || obj;
		return new F();
	}

	function remove(obj, name, safe) {
		if (safe) {
			var safeObj = {};
			for (var key in obj) {
				if (key !== name) safeObj[key] = obj[key];
			}
		} else {
			delete obj[name];
		}
		return safeObj || obj;
	}

	function extend(oldObj, newObj, preserve) {
		if (!oldObj || !newObj) return oldObj || newObj || {};
		oldObj = copy(oldObj);
		newObj = copy(newObj);
		for (var key in newObj) {
			if (Object.prototype.toString.call(newObj[key]) === '[object Object]') {
				extend(oldObj[key], newObj[key]);
			} else {
				oldObj[key] = (preserve && oldObj[key]) ? oldObj[key] : newObj[key];
			}
		}
		return oldObj;
	}

	function implement(array) {
		var collection = {};
		for (var i = 0; i < array.length; i++) {
			if (typeof (array[i]) === 'function') array[i] = array[i].prototype;
			var safe = remove(array[i], 'initialize', true);
			if (safe.implement) {
				collection = implement(safe.implement);
			} else {
				collection = extend(collection, safe);
			}
		}
		return collection;
	}
})(window);